#include "socket_channel.h"

#include "./../description_module/description_module.h"
#include "./../loop_module/loop.h"
#include "./../log_module/log_public_module.h"
#include <memory>

SocketChannel::SocketChannel(Loop * loop, const std::shared_ptr<Description> & description)
{
    m_loop        = loop;
    m_description = description;
    m_index       = -1;
    LOG_SOCKET_MODULE("Create SocketChannel(%p)", this);
}

SocketChannel::~SocketChannel()
{
    if (m_loop && m_index > 0)
    {
        m_loop->DelEvent(m_index);
    }
    m_loop        = nullptr;
    m_index       = 0;
    m_description = nullptr;
    LOG_SOCKET_MODULE("Release SocketChannel(%p)", this);
}

int SocketChannel::DescriptionData()
{
    return m_description->DescriptionData();
}

void SocketChannel::OnEvent(EventData & data)
{
    LOG_SOCKET_MODULE("SocketChannel(%p) OnEvent event(%d)", this, data.events);
    if ((data.events & EmIoIn && data.events & EmIoRdHup) || data.events & EmIoErr || data.events & EmIoRdHup)
    {
        OnErrorEvent(shared_from_this(), m_description);
    }
    else
    {
        if (data.events & EmIoIn)
        {
            OnReadEvent(shared_from_this(), m_description);
        }
        if (data.events & EmIoOut)
        {
            OnWriteEvent(shared_from_this(), m_description);
        }
        if (data.events & EmIoPost)
        {
            for (auto & fn : m_post_func)
            {
                fn();
            }
            m_post_func.clear();
        }
    }
}

int64_t SocketChannel::Index()
{
    return m_index;
}

void SocketChannel::Index(int64_t index)
{
    m_index = index;
}

int SocketChannel::AddEvent(int event)
{
    bool result = m_loop->AddEvent(shared_from_this(), event);
    LOG_SOCKET_MODULE("SocketChannel(%p) AddEvent add event(%d) result:%d index:%ld", this, event, result, m_index);
    return result == true;
}

int SocketChannel::ModEvent(int event)
{
    bool result = m_loop->ModEvent(m_index, event);
    LOG_SOCKET_MODULE("SocketChannel(%p) ModEvent modify event(%d) result:%d index:%ld", this, event, result, m_index);
    return result == true;
}

int SocketChannel::DelEvent()
{
    auto result = m_loop->DelEvent(m_index);
    if (result)
    {
        m_index = -1;
    }
    LOG_SOCKET_MODULE("SocketChannel(%p) DelEvent result:%d index:%ld", this, result, m_index);
    return result == true;
}

void SocketChannel::Post(PostFunc && func)
{
    LOG_SOCKET_MODULE("SocketChannel(%p) Post a task", this);
    m_post_func.push_back(func);
    m_loop->AddPostTask(shared_from_this());
}

void SocketChannel::OnWriteEvent(std::shared_ptr<SocketChannel>, std::shared_ptr<Description>)
{
}

void SocketChannel::OnReadEvent(std::shared_ptr<SocketChannel>, std::shared_ptr<Description>)
{
}

void SocketChannel::OnErrorEvent(std::shared_ptr<SocketChannel>, std::shared_ptr<Description>)
{
}
